package com.zhenyi.xhc.core;

import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.hashids.Hashids;
import org.joda.time.DateTime;

import com.cenjiawen.common.IndexController;
import com.cjw.model.DBMap;
import com.jfinal.aop.Before;
import com.jfinal.kit.HashKit;
import com.jfinal.kit.HttpKit;
import com.jfinal.kit.JsonKit;
import com.jfinal.kit.LogKit;
import com.jfinal.kit.PropKit;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.DbPro;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.weixin.sdk.api.PaymentApi;
import com.jfinal.weixin.sdk.api.PaymentApi.TradeType;
import com.jfinal.weixin.sdk.kit.IpKit;
import com.jfinal.weixin.sdk.kit.PaymentKit;
import com.utils.DateUtils;
import com.utils.PathUtils;
import com.utils.PayUtils;
import com.utils.Utils;
import com.xhc.common.model.XhcOrder;
import com.xhc.common.model.XhcWechat;
import com.zhenyi.core.VueUtils;
import com.zhenyi.core.interceptor.ReferenceInterceptor;

import cn.hutool.core.text.StrFormatter;
import cn.hutool.core.util.PageUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.setting.Setting;

//@Clear(AuthInterceptor.class)
@Before(ReferenceInterceptor.class)
public class XHCController extends IndexController {

	protected final String APP_ID = PropKit.get("XHC_APP_ID", "");
	protected final String APP_SECRET = PropKit.get("XHC_APP_SECRET", "");// b0442f55643cfa9309b445ff75945cd9

	// protected String settingPath = PathUtils.getFile("xhc", "xhc.setting");
	// protected Setting rootSetting = new Setting(settingPath);
	protected final int PAGE_SIZE = 50;
	protected Setting setting = new Setting("xhc.setting");
	protected Hashids hashids = new Hashids("xiaohuoche", 16);
	protected Hashids piaoHashids = new Hashids("piao", 8);
	// protected final String SECRET = setting.getStr("SECRET", "wechat", "");
	// protected final String APP_ID = setting.getStr("APP_ID", "wechat", "");
	protected final String PARTNER = PropKit.get("XHC_PARTNER", "");//
	// setting.getStr("PARTNER",
	// "wechat",
	// "");
	protected final String NOTIFY_URL = PropKit.get("XHC_NOTIFY_URL", "");// setting.getStr("NOTIFY_URL",
																			// "wechat",
																			// "");
	protected final String REFUND_NOTIFY_URL = PropKit.get("XHC_NOTIFY_URL", "");// setting.getStr("REFUND_NOTIFY_URL",
																					// "wechat",
																					// "");
	protected final String PARTNER_KEY = PropKit.get("XHC_PARTNER_KEY", "");// setting.getStr("PARTNER_KEY",
																			// "wechat",
																			// "");
	protected final String SSL_PATH = XHCPathUtils.getClassFile("wx6d47db34d18f5e3a", "apiclient_cert.p12");
	protected PayUtils payUtils = new PayUtils(APP_ID, PARTNER, PARTNER_KEY, SSL_PATH);
	protected String HOST = setting.getStr("host", "ticketSetting", "");
	protected String QRCODE_HOST = setting.getStr("qrcode", "ticketSetting", "");
	protected String QRCODE_VERIFY = setting.getStr("verify", "ticketSetting", "");
	protected String AES_KEY = PropKit.get("XHC_AES_KEY", "Bar12345Bar12345");
	protected OrderUtils orderUtils = new OrderUtils();

	protected DbPro xhcDb = Db.use("xhc");
	protected DbPro db = Db.use("xhc");
	protected final Integer ONE = 1;

	protected Integer getPageSize() {
		int pageSize = getParaToInt("pageSize", PAGE_SIZE);
		setAttr("pageSize", pageSize);
		return pageSize;
	}

	/**
	 * 整理数据库json
	 * 
	 * @param object
	 * @Time 2018年12月16日 下午5:34:20
	 */
	protected void setJsonItems(Object object) {
		setAttr("items", getJson(object));
	}

	protected void setData(String name, Object object) {
		if (object == null) {
			setAttr(name, "{}");
			return;
		}
		setAttr(name, VueUtils.getVueData(object));
	}

	protected String getJson(Object object) {
		try {
			String json = JsonKit.toJson(object);
			String str = ReUtil.escape(json);
			return str;
		} catch (Exception e) {
			return "{}";
		}
	}

	protected void setRainbow(Page<?> pages) {
		Integer requestPage = getParaToInt("page");

		HttpServletRequest request = getRequest();
		String url = request.getRequestURL().toString();
		String queryurl = request.getQueryString();
		if (StrKit.notBlank(queryurl)) {
			if (requestPage != null) {
				queryurl = queryurl.replace("&page=" + requestPage, "");
				queryurl = queryurl.replace("page=" + requestPage, "");
				if (StrKit.notBlank(queryurl)) {
					url = url + "?" + queryurl + "&page=";
				} else {
					url = url + "?page=";
				}
			} else {
				url = url + "?" + queryurl + "&page=";
			}
		} else {
			url = url + "?page=";
		}
		int pageTotal = pages.getTotalPage();
		int pageTotalRow = pages.getTotalRow();
		int page = pages.getPageNumber();
		int[] rainbow = PageUtil.rainbow(pages.getPageNumber(), pageTotal);
		setAttr("rainbow", rainbow);
		setAttr("pageUrl", url);
		setAttr("pageTotalRow", pageTotalRow);
		setAttr("pageSize", pages.getPageSize());
		setAttr("pageCurrent", page);
	}

	protected XhcOrder genOrder(String total, String raw, String attach) {
		String openId = getOpenId();
		XhcOrder order = new XhcOrder();
		order.setAddTime();
		String ip = IpKit.getRealIpV2(getRequest());
		order.setStatus(0);
		order.setPaidIp(ip);
		// order.setCardId(cardId);
		order.setOpenid(openId);
		order.setAddTime();
		order.setTotalFee(total);
		order.setPrice(Integer.parseInt(total));
		order.setAppId(APP_ID);
		order.setMchId(PARTNER);
		// order.setCount(count);
		// order.setShopId(shop.getId());
		order.setRaw(raw);
		order.setAttach(attach);
		order.save();
		order.setOutTradeNo(hashids.encode(order.getId()));
		order.update();
		return order;
	}

	protected Date getOpenTime(String date) {
		String openTime = PropKit.get("XHC_OPEN_TIME", "10:00");
		// new FileReader(PathUtils.getFile("xhc",
		// "openTime.txt")).readString();
		// String openTime = rootSetting.getStr("openTime", "ticketSetting",
		// "08");
		String time = date + " " + openTime;
		return DateUtils.dateFromString(time, DateUtils.YYYYMMDD_HHMM);
	}

	protected Date getCloseTime(String date) {
		String closeTime = PropKit.get("XHC_CLOSE_TIME", "20:30");
		// new FileReader(PathUtils.getFile("xhc",
		// "closeTime.txt")).readString();
		// String closeTime = rootSetting.getStr("closeTime", "ticketSetting",
		// "20");
		String time = date + " " + closeTime;
		return DateUtils.dateFromString(time, DateUtils.YYYYMMDD_HHMM);
	}

	@Override
	public void index() {
		renderDevelop();
	}

	protected String getOpenId() {
		return getPara("openId");
	}

	protected XhcWechat getWechat() {
		String openId = getOpenId();
		if (StrKit.isBlank(openId)) {
			return null;
		}
		return XhcWechat.dao.findByOpenId(getOpenId());
	}

	protected Map<String, Object> getSessionKey(String appid, String secret, String code) {
		String url = "https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code";
		url = url.replace("APPID", appid);
		url = url.replace("SECRET", secret);
		url = url.replace("JSCODE", code);
		String response = HttpKit.get(url);
		Map<String, Object> info = Utils.jsonToMap(response);
		return info;
	}

	protected void genQRCode(String text) {
		String qrcodeUrl = "http://qr.liantu.com/api.php?text={}&logo={}";
		String encodetUrl = URLUtil.encode(text);
		String logoUrl = setting.getStr("logoUrl", "ticketSetting", "");
		qrcodeUrl = StrFormatter.format(qrcodeUrl, encodetUrl, logoUrl);
		String path = PathUtils.getFile("xhc", "qrcode", text + ".png");
		File destFile = new File(path);
		if (destFile.exists()) {
			return;
		}
		HttpUtil.downloadFile(qrcodeUrl, destFile);
	}

	protected void genQRCode(String name, String content) {
		new Thread(new Runnable() {

			@Override
			public void run() {
				String qrcodeUrl = "http://www.liantu.com/api.php?text={}&logo={}";
				String encodetUrl = URLUtil.encode(content);
				String logoUrl = setting.getStr("logoUrl", "ticketSetting", "");
				qrcodeUrl = StrFormatter.format(qrcodeUrl, encodetUrl, logoUrl);
				String path = PathUtils.getFile("xhc", "qrcode", name + ".png");
				File destFile = new File(path);
				if (destFile.exists()) {
					return;
				}
				HttpUtil.downloadFile(qrcodeUrl, destFile);
			}
		}).start();
	}

	protected boolean DEBUG = PropKit.getBoolean("devMode", false);

	public String renderPay(String orderNo, String title, String total_fee, String openId) {
		return renderPay(orderNo, title, total_fee, openId, null);
	}

	public String renderPay(String orderNo, String title, String total_fee, String openId, String attach) {
		String nonce_str = System.currentTimeMillis() / 1000 + "";
		// String nonce_str = RandomUtil.randomString(32);
		String tradeNo = orderNo;

		if (DEBUG) {
			total_fee = "1";
		}

		Map<String, String> params = new HashMap<String, String>();
		params.put("appid", APP_ID);
		params.put("mch_id", PARTNER);
		params.put("body", title);
		params.put("out_trade_no", tradeNo);
		params.put("total_fee", total_fee);
		String ip = IpKit.getRealIp(getRequest());
		if (StrKit.isBlank(ip)) {
			ip = "127.0.0.1";
		}
		if (DEBUG) {
			ip = "127.0.0.1";
		}
		params.put("spbill_create_ip", ip);
		params.put("trade_type", TradeType.JSAPI.name());
		params.put("nonce_str", nonce_str);
		params.put("notify_url", NOTIFY_URL);
		params.put("openid", openId);
		params.put("sign_type", "MD5");
		if (StrKit.notBlank(attach)) {
			params.put("attach", attach);
		}
		String sign = PaymentKit.createSign(params, PARTNER_KEY);
		params.put("sign", sign);
		String xmlResult = PaymentApi.pushOrder(params);
		Map<String, String> result = PaymentKit.xmlToMap(xmlResult);

		if (DEBUG) {
			// LogKit.info(JsonKit.toJson(params));
			// LogKit.info(xmlResult);
			LogKit.info("NOTIFY_URL: " + NOTIFY_URL);
			LogKit.info("APP_ID: " + APP_ID);
			LogKit.info("PARTNER: " + PARTNER);
			LogKit.info("PARTNER_KEY: " + PARTNER_KEY + " - " + PARTNER_KEY.length());
			LogKit.info("trade_type: " + TradeType.JSAPI.name());
		}
		if (!PayUtils.isXMLSuccess(result)) {
			LogKit.info(xmlResult);
			renderMsg("支付出错");
			return null;
		}

		String prepay_id = result.get("prepay_id");
		DateTime dateTime = new DateTime();
		String timeStamp = dateTime.toDate().getTime() / 1000 + "";
		String signString = "appId=" + APP_ID + "&nonceStr=" + nonce_str + "&package=prepay_id=" + prepay_id
				+ "&signType=MD5&timeStamp=" + timeStamp + "&key=" + PARTNER_KEY;
		signString = HashKit.md5(signString).toUpperCase();
		DBMap map = new DBMap();
		map.put("result", result);
		map.put("sign", signString);
		map.put("timeStamp", timeStamp);
		map.put("nonce_str", nonce_str);
		// order.setPrepayId(prepay_id);
		// order.update();
		renderResult(map, "pay", 201);
		return prepay_id;
	}

	protected Date getStartDate() {
		return getStartDate("startDate", false);
	}

	protected Date getStartDate(String name, boolean allowNull) {
		String dateString = getPara(name);
		if (StrKit.isBlank(dateString) && allowNull) {
			return null;
		}
		if (StrKit.notBlank(dateString) && dateString.contains(":")) {
			try {
				setAttr(name, dateString);
				return DateUtils.dateFromString(dateString, DateUtils.YYYYMMDD_HHMMSS);
			} catch (Exception e) {
			}
		}
		Date date = new Date();
		date = new DateTime(date).minusDays(0).toDate();
		String fmt = DateUtils.dateFormat(date, DateUtils.YYYYMMDD);
		setAttr(name, fmt + " 00:00:00");
		return DateUtils.dateFromString(fmt + " 00:00:00", DateUtils.YYYYMMDD_HHMMSS);
	}

	protected Date getEndDate() {
		return getEndDate("endDate", false);
	}

	protected Date getEndDate(String name, boolean allowNull) {
		String dateString = getPara(name);
		if (StrKit.isBlank(dateString) && allowNull) {
			return null;
		}
		if (StrKit.notBlank(dateString) && dateString.contains(":")) {
			try {
				setAttr(name, dateString);
				return DateUtils.dateFromString(dateString, DateUtils.YYYYMMDD_HHMMSS);
			} catch (Exception e) {
			}
		}
		Date date = new Date();
		String fmt = DateUtils.dateFormat(date, DateUtils.YYYYMMDD);
		setAttr(name, fmt + " 23:59:59");
		return DateUtils.dateFromString(fmt + " 23:59:59", DateUtils.YYYYMMDD_HHMMSS);
	}

}
